home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************
- * *
- * Minimal Term for DNET (uc) Stone, SST *
- * Further modifications by Unknown, SST *
- * pterm name startupfile *
- * the startup file is used as tho input had come from *
- * stdin (ie keyboard or pipe or what ever) *
- * *
- * Set ya TABS to 4! *
- * Email me!! c9107253@mystra.newcastle.edu.au *
- * For any reason!! (eg DNet, AmiNet, Demos, amigas...) *
- * Please send any changes U make! *
- * *
- * Breaks out of search for port with ctrl-D *
- * all others kill program *
- * *
- * Mega-thanx to Azza of the SST for hours of DNET source *
- * modification.... yes it compiles under SAS 6! *
- **********************************************************/
-
- /* Multi input system: this one has input from shell */
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <dos/dos.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <string.h>
-
- #include <st/textmessage.h>
- #include <st/st_proto.h>
-
- #define DEFHELPCHAR '?'
- #define EOLN 13,10
- #define ctrlSEQ '^'
- #define ctrlLEN 1
-
- #define cmdSEQ '\\'
- #define cmdLEN 1
-
-
- #define NOPORTDELAY 60 /* delay when checking for non-existant port */
-
- /* THese are the CTRL-Signals ONLY! */
- #define SIGNALS (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F)
-
- char things0[] = { 10, 13, 0 },
- things1[] = { 10, 0 },
- things2[] = { 13, 0 },
- things3[] = { 8, 0 },
- things4[] = { 13, 10, 0 },
- *ctrlWHITE = "^\n\r ",
- *WHITE = " \t\n\r",
- *eolntok = "\n\r";
-
- /* Every second one is the command command. Send \ followed by command*/
-
- char *cmds[] = {
- "LFCR", things0, "LF & CR at transmit end of line",
- "CRLF", things4, "CR & LF at end of line",
- "LF", things1, "LF end of line",
- "CR", things2, "CR end of line",
- "BS", things3, "back space character",
- "PROMPTOFF", NULL, "main prompt off",
- "PROMPT", NULL, "main prompt on",
- "PORT", NULL, "new destination port (eg \p mystra1)",
- "P", NULL, "new destination port (eg \p mystra1)",
- "AUTOKILLOFF",NULL, "don't kill server with exit",
- "AUTOKILL" ,NULL, "kill server with exit (\q kills us & server)",
- "AUTOEXITOFF",NULL, "don't exit when destination port not found",
- "AUTOEXIT" ,NULL, "auto exit when destination port not found",
- "WAITFORPORTOFF", NULL,"ignore input if no dest port",
- "WAITFORPORT",NULL, "wait for dest port to appear when sending",
- "EXECUTE", NULL, "send a command to the AmigaShell",
- "X", NULL, "send a command to the AmigaShell",
- "QUOTE", NULL, "send string as command to server",
- "I", NULL, "Ask server for help/info",
- "H", NULL, "Ask server for help/info",
- "Q", NULL, "Quit/exit this p-term",
- "E", NULL, "Quit/exit this p-term"
- };
-
- /* if there are common parts of words (eg promptoff & prompt) makesure
- the larger (promptoff) comes before */
-
- #define CMDDIST 3 /* strings/command */
-
- #define CMD_LFCR 0
- #define CMD_CRLF 1
- #define CMD_LF 2
- #define CMD_CR 3
- #define CMD_BS 4
- #define CMD_PROMPTOFF 5
- #define CMD_PROMPT 6
- #define CMD_PORT 7
- #define CMD_P 8
- #define CMD_AUTOKILLOFF 9
- #define CMD_AUTOKILL 10
- #define CMD_AUTOEXITOFF 11
- #define CMD_AUTOEXIT 12
- #define CMD_WAITFORPORTOFF 13
- #define CMD_WAITFORPORT 14
- #define CMD_EXECUTE 15
- #define CMD_X 16
- #define CMD_QUOTE 17
- #define CMD_I 18
- #define CMD_H 19
- #define CMD_Q 20
- #define CMD_E 21
- #define CMDCNT 22
-
- /* port-terminal attributes & characteristics */
- /* these may be modified at anytime */
- #define MAXPNAMESIZE 99
-
-
- /* Return codes of functions */
- #define RET_QUIT 0
- #define RET_OK 0x0001
- #define RET_CTRLC 0x0f00
- #define RET_CTRLD 0x0f10
- #define RET_CTRLE 0x0f20
- #define RET_CTRLF 0x0f30
- #define RET_HALTC 0x0e00
- #define RET_HALTD 0x0e10
- #define RET_HALTE 0x0e20
- #define RET_HALTF 0x0e30
- #define RET_NOPORT 0x0002
- #define RET_NOTHING 0x0003
-
- char eoln[10] = { EOLN,0 },
- ctrlseq[10] = { ctrlSEQ,0 }, ctrllen = ctrlLEN,
- cmdseq[10] = { cmdSEQ,0 }, cmdlen = cmdLEN,
- helpchar = DEFHELPCHAR,
-
- *prompt = "%s > ",
- mainprompt = 0,
- autoexit = 0,
- waitport = 0,
- autokillserver = 0,
- destportname[MAXPNAMESIZE + 2],
-
- stringbuf[400],
- *progname;
-
- /* Standard Output() */
- long output;
-
- /*********************************************************/
- long Readln(BPTR file, char *buffer, long max)
- /*********************************************************
- Attempt to read a line of stuff.
- return 0 on the end of a file
- Uses the nasty method of reading one character at a time
- (sorry) throws away line on eof
- **********************************************************/
- {
- long i = 0;
- do {
- if(!Read(file, &buffer[i], 1))
- return(0);
- } while(!charinstr(buffer[i++], eolntok) && (i < max-1) );
- buffer[i] = '\0';
- return(i);
- }
-
-
-
- /*********************************************************/
- BOOL SafePutToPort(struct Message *message, char *portname)
- /*********************************************************
- Only put to the port if it exists!
- Forbid first then test for the port
- Return NULL if port couldn't be found
- **********************************************************/
- {
- struct MsgPort *port;
-
- Forbid();
- if (port = FindPort(portname)) PutMsg(port,message);
- Permit();
- return((BOOL)port); /* If zero, the port has gone away */
- }
-
-
- /*********************************************************/
- short SendTextMessage(char *portname,
- struct TextMessage *txtmsg, struct MsgPort *ourport)
- /*********************************************************
- Try to send a text message to a port of name "name"
- Breaks sent to us cause us to quit
- **********************************************************/
- {
- ULONG mask, pmask = 1 << ourport->mp_SigBit;
- struct TextMessage *currtxtmsg;
-
- /* just in case our replier doesn't */
- AllocString0(&(txtmsg->RepString),0);
-
- while(! SafePutToPort((struct Message *)txtmsg,portname) ) {
- fpf(output,"Destination port not found (CTRL-C to ignore)..\n");
- if(autoexit) return(RET_QUIT);
- if(!waitport) return(RET_NOPORT);
- /* Where is that port??? Might hang around... just in case. */
- Delay(NOPORTDELAY);
- mask = SetSignal(0,SIGNALS); /* Set all CTRL signals to 0 */
- /* If we got a control signal... quit */
- if(mask & SIGBREAKF_CTRL_C) return(RET_HALTC);
- else if(mask & SIGBREAKF_CTRL_D) return(RET_HALTD);
- else if(mask & SIGBREAKF_CTRL_E) return(RET_HALTE);
- else if(mask & SIGBREAKF_CTRL_F) return(RET_HALTF);
- }
-
- /* now we must wait for the reply! */
- for(;;) {
- mask = Wait(pmask | SIGNALS);
- if(mask & pmask) {
- while (currtxtmsg =
- (struct TextMessage *) GetMsg(ourport)) {
-
- /* Write out contents of the reply string if need be */
- if(currtxtmsg->RepString.String) {
- Write(output, currtxtmsg->RepString.String,
- STRLEN(&(currtxtmsg->RepString)));
- SafeFreeString0(&(currtxtmsg->RepString));
- }
-
- /* Got our funky text back */
- return(RET_OK);
- }
- }
- if((mask & SIGBREAKF_CTRL_C) ||
- (mask & SIGBREAKF_CTRL_D) ||
- (mask & SIGBREAKF_CTRL_E) ||
- (mask & SIGBREAKF_CTRL_F) ) {
- fpf(output,"Sorry, waiting for a reply from '%s'\n",portname);
- }
- }
- }
-
-
- /*********************************************************/
- short DoCmdSendTM(char *string, char *send,
- struct TextMessage *msg, struct MsgPort *ourport)
- /*********************************************************
- Pass a string with a user command on it and this will try
- to do stuff from that!
- modifies terminal characteristics & the like
- if command is unknown pass first 120 bytes of string
- to server
- returns 1 if textmessage should be sent
- OR 0 if unknown command
- OR -1 if a QUIT command was received
- **********************************************************/
- {
- char *argument, *command, *rest, backup[120];
- short i;
-
- strncpy(backup,string,119);
- backup[119] = '\0';
- command = strtok(string,WHITE);
- rest = strtok(NULL,NULL);
- strupper(command);
-
- for(i = 0; i < CMDCNT*CMDDIST; i += CMDDIST) {
- if(strncmp(command,cmds[i],strlen(cmds[i])) == 0) {
- switch((i+CMDDIST-1)/CMDDIST) {
- case CMD_LFCR:
- case CMD_CRLF:
- case CMD_LF:
- case CMD_CR:
- strcpy(eoln,cmds[i+1]);
- fpf(output,"\nSending %s\n",cmds[i+2]);
- return(RET_OK);
-
- case CMD_BS:
- strcpy(send,cmds[i+1]);
- msg->String.StrLen = -1;
- msg->String.FreeLen = 0;
- msg->String.String = send;
- msg->Command = TM_TEXT;
- fpf(output,"\nSending %s\n",cmds[i+2]);
- return(SendTextMessage(destportname,msg,ourport));
-
- case CMD_PROMPT:
- mainprompt = -1;
- fpf(output,"\n%s\n",cmds[i+2]);
- return(RET_OK);
-
- case CMD_PROMPTOFF:
- mainprompt = 0;
- fpf(output,"\n%s\n",cmds[i+2]);
- return(RET_OK);
-
- case CMD_PORT:
- case CMD_P:
- argument = strtok(rest,WHITE);
- if(argument == NULL) {
- fpf(output,"\nUSE: %s %s (currently port is '%s')\n",
- cmds[i],cmds[i+2],destportname);
- } else {
- fpf(output,"\nPort is now '%s' (Old port was '%s')\n",
- argument,destportname);
- strncpy(destportname,argument,MAXPNAMESIZE);
- }
- return(RET_OK);
-
- case CMD_AUTOKILL:
- autokillserver = 1;
- return(RET_OK);
-
- case CMD_AUTOKILLOFF:
- autokillserver = 0;
- return(RET_OK);
-
- case CMD_AUTOEXIT:
- autoexit = 1;
- return(RET_OK);
-
- case CMD_AUTOEXITOFF:
- autoexit = 0;
- return(RET_OK);
-
- case CMD_WAITFORPORT:
- waitport = 1;
- return(RET_OK);
- case CMD_WAITFORPORTOFF:
- waitport = 0;
- return(RET_OK);
-
- case CMD_QUOTE: /* send out a command to receiver */
- fpf(output,"Sending command '%s'\n",rest);
- strcpy(send,rest);
- msg->String.StrLen = -1;
- msg->String.FreeLen = 0;
- msg->String.String = send;
- msg->Command = TM_COMMAND;
- return(SendTextMessage(destportname,msg,ourport));
-
- case CMD_X:
- case CMD_EXECUTE: /* Send command to amiga dos! */
- fpf(output,"Executing '%s'\n",rest);
- Execute(rest, NULL, output);
- return(RET_OK);
-
- case CMD_I:
- case CMD_H:
- msg->String.StrLen = 0;
- msg->String.FreeLen = 0;
- msg->String.String = NULL;
- msg->Command = TM_HELP;
- fpf(output,"\nAsking for server commands\n");
- return(SendTextMessage(destportname,msg,ourport));
-
- case CMD_Q: case CMD_E:
- if(autokillserver) {
-
- msg->String.StrLen = 0;
- msg->String.FreeLen = 0;
- msg->String.String = NULL;
- msg->Command = TM_EXIT;
- waitport = 0; /* Make sure we don't stick around */
- SendTextMessage(destportname,msg,ourport);
- }
- return(RET_QUIT);
-
- }
- }
- }
-
- /* otherwise send off the command to the server - we couldn't interpret */
- msg->String.StrLen = -1;
- msg->String.FreeLen = 0;
- msg->String.String = backup;
- msg->Command = TM_COMMAND;
- return(SendTextMessage(destportname,msg,ourport));
-
- }
-
-
- /*********************************************************/
- short DoInput(char *instring,
- struct TextMessage *txtmsg, struct MsgPort *ourport)
- /*********************************************************
- string buf is usually trashed after this!
- **********************************************************/
- {
- char *temppos;
- short i;
-
- /* DEFAULT VALUES FOR THE TEXT MESSAGE */
- txtmsg->Extra = NULL;
- for(i = 0; i < 8; txtmsg->Args[i++] = 0);
-
- /* CHECK FOR THE COMMAND SEQUENCE (THAT'S A '\' ON A NEW LINE) */
- if( strncmp(instring,cmdseq,cmdlen) == 0) {
-
- while(strncmp(instring,cmdseq,cmdlen) == 0) instring += cmdlen;
-
- /* PRINT HELP TO THE USER */
- if(*instring == helpchar) {
- fpf(output,"\nCharacter sequences:\n");
- for(i = 0; i< CMDCNT*CMDDIST; i += CMDDIST) {
- fpf(output,"\\%s\t:%s\n",cmds[i],cmds[i+2]);
- }
- }
- else if(*instring)
- return(DoCmdSendTM(instring, instring, txtmsg, ourport));
- else return(RET_NOTHING);
- }
-
- /* SEND CONTROL CHARACTERS? */
- else if( strncmp(instring,ctrlseq,ctrllen) == 0) {
- while(strncmp(instring,ctrlseq,ctrllen) == 0)
- instring += ctrllen;
- strupper(instring);
-
- /* 'a'-> 1, 'b' -> 2, 'c' -> 3 etc */
- for(temppos = instring;
- *temppos && !charinstr(*temppos,eoln); temppos++)
- *temppos -= ('A' - 1);
- if(temppos != instring)
- fpf(output,"\nSending control characters!\n");
- *temppos = '\0';
-
- } else
- strcat(instring,eoln);
-
- if( txtmsg->String.StrLen = strlen(instring) ) {
- txtmsg->String.String = instring;
- txtmsg->String.FreeLen = 0;
- txtmsg->Command = TM_TEXT;
- return(SendTextMessage(destportname, txtmsg, ourport));
- }
-
- return(RET_NOTHING);
- }
-
- /*********************************************************/
- int main(int argc, char **argv)
- /*********************************************************/
- {
- struct MsgPort *ourport = 0;
- struct TextMessage *txtmsg = 0;
-
- BPTR startup, input;
-
- output = Output();
- input = Input();
-
- fpf(output,"PTERM Terminal end shell version [shell->port] (uc) Stone, SST\n"
- "email: c9107253@mystra.newcastle.edu.au (1993)\n");
-
- if( argc<2 ) {
- fpf(output,"Use: %s [>file] [<file] portname [startupfile]\n"
- "(This portname has NOTHING to do with the DNET ports)\n",argv[0]);
- return(5);
- }
-
- progname = argv[0];
- strncpy(destportname,argv[1],MAXPNAMESIZE + 1);
- /* Make sure completely padded with \0 */
-
- fpf(output,"Sending lines to port '%s'\n"
- "Current control character prefix is '%s'\n"
- "'%s%lc' for help!\n\n", destportname, ctrlseq, cmdseq, helpchar);
-
- if( !(ourport = CreatePort(0,0)) ) {
- fpf(output,"Reply port will not open!\n");
- goto enditnow;
- }
-
- if( !(txtmsg = (struct TextMessage *)
- AllocMem(sizeof(struct TextMessage), MEMF_PUBLIC)) ) {
- fpf(output,"Sorry.. Not enough memory for message structure\n");
- goto enditnow;
- }
-
- /* WRITE MESSAGE DEFAULTS? */
- txtmsg->Msg.mn_Node.ln_Type = NT_MESSAGE;
- txtmsg->Msg.mn_Length = sizeof(struct TextMessage);
- txtmsg->Msg.mn_ReplyPort = ourport;
-
-
- /* READ A STARTUP FILE? */
- if(argc >= 3) {
- if(startup = Open(argv[2],MODE_OLDFILE)) {
- while( Readln(startup, stringbuf, 300) ) {
- if(!strtok(stringbuf, eolntok))
- stringbuf[0] = '\0';
- if( DoInput(stringbuf, txtmsg, ourport) == RET_QUIT)
- goto enditnow;
- }
- Close(startup);
- }
- else
- fpf(output,"Startup file '%s' not found.\n",argv[2]);
- }
-
- /* READ WHAT STDIN HAS TO GIVE US */
- do {
- if(mainprompt) fpf(output,prompt,destportname);
- if(! Readln(input, stringbuf, 300) ) {
- fpf(output,"\nEOF\n");
- goto enditnow;
- }
- if(!strtok(stringbuf, eolntok)) /* remove eoln characters */
- stringbuf[0] = '\0';
-
- } while(DoInput(stringbuf, txtmsg, ourport) != RET_QUIT);
-
- enditnow:
- if(ourport) {
- Forbid();
- /* There should be no pending messages... if there are then
- something is very wrong and the system is probably stuffed.. */
- while((struct TextMessage *) GetMsg(ourport));
- DeletePort(ourport);
- Permit();
- }
-
- if(txtmsg) FreeMem(txtmsg,sizeof(struct TextMessage));
- return(0);
- }
-
-